module log
  integer*4 :: logunit
  character(len=16)  :: logfile
  character(len=512) :: mystring
end module log

module params_and_constants
  type conv_type
     real*8 :: CGSConversionFactor
     real*8 :: h_scale_exponent
     real*8 :: aexp_scale_exponent
  end type conv_type
  type conversion_data
     type(conv_type) :: Coordinates
     type(conv_type) :: Velocity
     type(conv_type) :: Mass
     type(conv_type) :: Density
     type(conv_type) :: Temperature
     type(conv_type) :: SmoothingLength
     type(conv_type) :: Time_GYR
     type(conv_type) :: Luminosity
  end type conversion_data
  type units_data
     real*8 :: UnitLength_in_cm
     real*8 :: UnitMass_in_g
     real*8 :: UnitVelocity_in_cm_per_s
     real*8 :: UnitDensity_in_cgs
     real*8 :: UnitEnergy_in_cgs
     real*8 :: UnitPressure_in_cgs
     real*8 :: UnitTime_in_s
  end type units_data
  type constants_data
     real*8 :: PI
     real*8 :: GAMMA
     real*8 :: GRAVITY
     real*8 :: SOLAR_MASS
     real*8 :: SOLAR_LUM
     real*8 :: RAD_CONST
     real*8 :: AVOGADRO
     real*8 :: BOLTZMANN
     real*8 :: GAS_CONST
     real*8 :: C
     real*8 :: PLANCK
     real*8 :: CM_PER_MPC
     real*8 :: PROTONMASS
     real*8 :: ELECTRONMASS
     real*8 :: ELECTRONCHARGE
     real*8 :: HUBBLE
     real*8 :: T_CMB0
     real*8 :: SEC_PER_MEGAYEAR
     real*8 :: SEC_PER_YEAR
     real*8 :: STEFAN
     real*8 :: THOMPSON
     real*8 :: EV_TO_ERG
     real*8 :: Z_Solar
  end type constants_data
  type parameters_data
     integer*4 :: BG_NELEMENTS
     character(len=20), dimension(9) :: ElementNames
     real*8 :: InitAbundance_Hydrogen
     real*8 :: InitAbundance_Helium
     real*8 :: InitAbundance_Carbon
     real*8 :: InitAbundance_Nitrogen
     real*8 :: InitAbundance_Oxygen
     real*8 :: InitAbundance_Neon
     real*8 :: InitAbundance_Magnesium
     real*8 :: InitAbundance_Silicon
     real*8 :: InitAbundance_Iron
     real*8 :: CalciumOverSilicon
     real*8 :: SulphurOverSilicon
     integer*4 :: ComovingIntegrationOn
     integer*4 :: TypeOfTimeStepCriterion
     real*8 :: ErrTolIntAccuracy
     real*8 :: MaxSizeTimestep
     real*8 :: MinSizeTimestep
     real*8 :: ErrTolTheta
     integer*4 :: TypeOfOpeningCriterion
     real*8 :: ErrTolForceAcc
     real*8 :: TreeDomainUpdateFrequency
     integer*4 :: DesNumNgb
     real*8 :: MaxNumNgbDeviation
     real*8 :: ArtBulkViscConst
     real*8 :: InitGasU_ERG
     real*8 :: MinGasU_ERG
     real*8 :: CourantFac
     real*8 :: PartAllocFactor
     real*8 :: TreeAllocFactor
     real*8 :: BufferSize
     real*8 :: MinGasHsmlFractional
     real*8 :: SF_EOSGammaEffective
     real*8 :: SF_EOSEnergyAtThreshold_ERG
     real*8 :: SF_THRESH_MinPhysDens_HpCM3
     real*8 :: SF_THRESH_MinOverDens
     real*8 :: SF_THRESH_MetDepExponent
     real*8 :: SF_THRESH_MetDepFiducialZ
     real*8 :: SF_THRESH_MetDepMaxPhysDens_HpCM3
     real*8 :: SF_THRESH_MaxTemp_K
     real*8 :: SF_SchmidtLawCoeff_MSUNpYRpKPC2
     real*8 :: SF_SchmidtLawExponent
     real*8 :: SF_SchmidtLawCoeff_GpSpCM2
     integer*4 :: SF_MetDepDensThresholdOn
     character(len=100) :: IMF_Model
     character(len=100) :: IMF_LifetimeModel
     real*8 :: IMF_MinMass_MSUN
     real*8 :: IMF_MaxMass_MSUN
     character(len=100) :: SNIa_Model
     real*8 :: SNIa_Efficiency_fracwd
     real*8 :: SNIa_Energy_ERG
     integer*4 :: SNIa_MassTransferOn
     integer*4 :: SNIa_EnergyTransferOn
     integer*4 :: SNII_MassTransferOn
     real*8 :: SNII_MinMass_MSUN
     real*8 :: SNII_MaxMass_MSUN
     real*8 :: SNII_Factor_Hydrogen
     real*8 :: SNII_Factor_Helium
     real*8 :: SNII_Factor_Carbon
     real*8 :: SNII_Factor_Nitrogen
     real*8 :: SNII_Factor_Oxygen
     real*8 :: SNII_Factor_Neon
     real*8 :: SNII_Factor_Magnesium
     real*8 :: SNII_Factor_Silicon
     real*8 :: SNII_Factor_Iron
     integer*4 :: AGB_MassTransferOn
     integer*4 :: POPIII_MassTransferOn
     integer*4 :: POPIII_EnergyTransferOn
     real*8 :: POPIII_Energy_ERG
     real*8 :: POPIII_NumPerMsun
     integer*4 :: SNII_WindOn
     integer*4 :: SNII_WindIsotropicOn
     real*8 :: SNII_WindSpeed_KMpS
     real*8 :: SNII_WindMassLoading
     real*8 :: SNII_WindDelay_YR
  end type parameters_data
  type header_data
     character(len=200) :: RunLabel
     integer*4, dimension(0:5) :: NumPart_ThisFile  ! Don't write this out makes no sense
     integer*4, dimension(0:5) :: NumPart_Total
     integer*4, dimension(0:5) :: NumPart_Total_HighWord
     real*8, dimension(0:5) :: MassTable
     real*8 :: ExpansionFactor
     real*8 :: Time_GYR
     real*8 :: Redshift
     real*8 :: Boxsize
     integer*4 :: NumFilesPerSnapshot
     real*8 :: Omega0
     real*8 :: OmegaBaryon
     real*8 :: OmegaLambda
     real*8 :: HubbleParam
     integer*4 :: Flag_Sfr
     integer*4 :: Flag_Cooling
     integer*4 :: Flag_StellarAge
     integer*4 :: Flag_Metals
     integer*4 :: Flag_Feedback
  end type header_data
  type(conversion_data)     :: Conv
  type(units_data)          :: Units
  type(constants_data)      :: Constants
  type(parameters_data)     :: Parameters
  type(header_data)         :: Header
  real*4 :: AB_VegaZeroPoint
  real*4 :: AB_SolarZeroPoint
  real*4, parameter :: Vega_V_Magnitude  = 0.00
  real*4, parameter :: Solar_V_Magnitude = 4.81
  real*4, parameter :: cgs_offset = -48.60           ! BC03 uses this value, so does Marcel
  real*8            :: Dcom ! Comoving distance
  real*8            :: DLum ! Luminosity distance
  real*8            :: Lum_to_Flux 
  real*8            :: Flux_to_Photons 
end module params_and_constants

module myfiles
  integer*4          :: final_snap,mode
  integer*4          :: output_handle
  real*4             :: x0,y0,z0,r0
  character(len=16)  :: suffix,suffix2
  character(len=16)  :: cfinal_snap,cmode,cx0,cy0,cz0,cr0,cfile,csnap
  character(len=512) :: paramfile
  character(len=512) :: basedir,basefile
  character(len=512) :: snapfile,outdir,outpath,outfile,infile
  logical            :: first_write = .TRUE.
end module myfiles

module particles
  integer*4, dimension(0:5) :: iSpecies_list
  integer*4  :: MyParticleNumbers(0:5), TotalParticleNumbers(0:5)
  integer*4, allocatable :: indx(:)
  integer*4,parameter, dimension(0:5) :: iread=(/1,1,1,1,1,1/)
  
  ! All we need are Coordinates and ParticleIDs
  type snapshot
     real*4, dimension(0:2) :: Coordinates
     real*4                 :: Mass
     integer*4              :: ParticleIDs
     integer*4              :: Index
  end type snapshot
  type(snapshot), allocatable, dimension(:) :: Type0
  type(snapshot), allocatable, dimension(:) :: Type1
  type(snapshot), allocatable, dimension(:) :: Type2
  type(snapshot), allocatable, dimension(:) :: Type3
  type(snapshot), allocatable, dimension(:) :: Type4
  type(snapshot), allocatable, dimension(:) :: Type5
  integer*4, dimension(0:5)                 :: NumSelected
  integer*4, dimension(0:5)                 :: NumGathered

  type selection_type
     integer*4 :: Index
     integer*4 :: ParticleIDs
     real*4    :: Coordinates(0:2)
  end type selection_type
  type(selection_type), allocatable :: Type0_tmp(:)
  type(selection_type), allocatable :: Type1_tmp(:)
  type(selection_type), allocatable :: Type2_tmp(:)
  type(selection_type), allocatable :: Type3_tmp(:)
  type(selection_type), allocatable :: Type4_tmp(:)
  type(selection_type), allocatable :: Type5_tmp(:)
  type(selection_type), allocatable :: Type0_Selection(:)
  type(selection_type), allocatable :: Type1_Selection(:)
  type(selection_type), allocatable :: Type2_Selection(:)
  type(selection_type), allocatable :: Type3_Selection(:)
  type(selection_type), allocatable :: Type4_Selection(:)
  type(selection_type), allocatable :: Type5_Selection(:)

  ! For indices of traces particle, we just want a counter of how many 
  ! particles in each type (stars and gas not individually conserved) and
  ! arrays for *just* the Index in the snapshot (can get ParticleIDs from snapshot)
  integer*4, dimension(0:5) :: NumTraced
  integer*4, allocatable    :: Type0_Traced_Index(:)
  integer*4, allocatable    :: Type1_Traced_Index(:)
  integer*4, allocatable    :: Type2_Traced_Index(:)
  integer*4, allocatable    :: Type3_Traced_Index(:)
  integer*4, allocatable    :: Type4_Traced_Index(:)
  integer*4, allocatable    :: Type5_Traced_Index(:)

  ! Centre of mass
  real*4 :: COM(0:2)

end module particles

